Par Nicolas Simond
7 mai 2020
Dans GNU/Linux
M
Bonjour à tous,
Aujourd’hui, petite procédure pour mettre en place les images au format WebP sur son site avec NGINX.
WebP est un format d’image matricielle développé et mis à disposition du public par Google. Il exploite un algorithme de compression avec pertes prédictif utilisé pour les images clés (en) du VP8 (qui est le codec vidéo du format WebM) et un conteneur léger et extensible RIFF1,2.
Google le présente comme mieux adapté que les compresseurs précédents aux processeurs actuels et surtout aux densités de pixels des écrans actuels (110 à 240 ppi). Par ailleurs, toujours selon Google, 60 % des octets transmis sur la toile seraient des images, et WebP procurerait de 30 % à 80 % de réduction d’espace face à JPEG et PNG3.
Source : https://fr.wikipedia.org/wiki/WebP
Ce qu’il faut retenir ? C’est un nouveau format d’image qui permet de réduire de 30 à 80% l’espace qu’occupent vos images. Et donc le volume de données nécessaire au final sur la bande passante de votre serveur et sur les informations que vos visiteurs téléchargements.
C’est tout bénef.
Mais la question étant, pourquoi est-ce que l’on en parle que maintenant alors que ça 10 ans ? L’adoption !
Concrètement, c’est à peu près supporté par tout le monde sauf Apple / Safari (tiens alors) et Internet Explorer depuis 2019, avant c’était beaucoup de travail pour pas grand-chose.
Ici, on ne va pas se contenter de simplement mettre en place le WebP, on va aussi optimiser toutes les images existantes en JPG, JPEG et PNG et ensuite on convertira tout automatiquement en WebP.
Pour cela on va utiliser le magnifique script fourni par Thomas disponible ici : https://github.com/VirtuBox/img-optimize
Attention, je ne fais pas une installation globale, simplement sous un utilisateur spécifique, car je n’ai qu’un seul site sur mon serveur qui dispose d’images, ce blog (c’est dingue non ?).
Prévoyez du temps pour la première conversion.
Connectez-vous avec votre utilisateur, tap pour ma part (j’aime les choses simples).
Installez les pré-requis :
sudo apt install jpegoptim optipng webp -y
Téléchargez le script et créez l’alias de commande pour l’utilisateur local :
git clone https://github.com/VirtuBox/img-optimize.git $HOME/.img-optimize
echo "alias img-optimize=$HOME/.img-optimize/optimize.sh" >> $HOME/.bashrc
source $HOME/.bashrc
Maintenant, rendez-vous dans le dossier où se trouvent les images de site, par exemple pour mon wordpress :
cd /var/www/wordpress/abyssproject.net/wp-content/uploads/
Et lancez le script en mode interactif :
img-optimize -i
Répondez “Y” à toutes les questions :
Cela va prendre beaucoup de temps selon le nombre d’images que vous avez (il m’a fallu 48h pour vous donner une idée, il y a des cadavres sur le blog au bout de 8 ans).
Une fois que tout sera fait sans erreur, vous aurez enfin toutes vos images, en jpg, en png et surtout en webp. Pas mal.
Pas mal ? Pas vraiment, vous allez surement ajouter des images, et vous n’allez pas faire l’optimisation à chaque fois, l’idée c’est de faire une optimisation à chaque fois, uniquement avec les fichiers modifiés durant les dernières 24h.
Créez un répertoire log dans votre user :
mkdir $HOME/log
Maintenant, créez le premier script d’optimisation des images jpg-png (en modifiant le nom d’utilisateur et le répertoire des images évidemment) :
nano $HOME/jpg-png-cron.sh
#!/bin/bash
## cronjob to optimize PNG/JPG images
## images path are listed in sites.csv
## written by VirtuBox (https://virtubox.net)
sites="/var/www/wordpress/abyssproject.net/wp-content/uploads/"
for site in $sites; do
# optimize jpg images created in the last 24 hours
find "$site" -ctime 0 -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -print0 | xargs -0 jpegoptim --preserve --strip-all -m82 >> /home/tap/log/jpg-png-cron.log 2>&1
# optimize png images created in the last 24 hours
find "$site" -ctime 0 -type f -iname '*.png' -print0 | xargs -0 optipng -o7 -strip all >> /home/tap/log/jpg-png-cron.log 2>&1
done
Créez ensuite celui pour la conversion en webp (en modifiant le nom d’utilisateur et le répertoire des images évidemment) :
nano $HOME/webp-cron.sh
#!/bin/bash
## cronjob to convert PNG/JPG images to WebP
## images path are listed in sites.csv
## written by VirtuBox (https://virtubox.net)
sites="/var/www/wordpress/abyssproject.net/wp-content/uploads/"
for site in $sites; do
# convert png created in the last 24 hours to webp
{
find "$site" -ctime 0 -type f -iname "*.png" -print0 | xargs -0 -I {} \
bash -c '[ ! -f "{}.webp" ] && { cwebp -z 9 -mt {} -o {}.webp; }' >> /home/tap/log/webp-cron.log 2>&1
# convert jpg created in the last 24 hours to webp
find "$site" -ctime 0 -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -print0 | xargs -0 -I {} \
bash -c '[ ! -f "{}.webp" ] && { cwebp -q 82 -mt {} -o {}.webp; }'
} >> /home/tap/log/webp-cron.log 2>&1
done
Maintenant, ouvrez le crontab de l’utilisateur :
crontab -e
Programmez l’optimisation automatique (tous les jours à 4h du matin par exemple) :
0 4 * * * /home/tap/jpg-png-cron.sh && /home/tap/webp-cron.sh > /dev/null 2>&1
Maintenant, la partie qui va vite, la configuration du serveur Web Nginx.
Pas d’inquiétude, je vous préviens en avance que vous verrez toutes les url de vos images en .png et .jpg/.jpeg, mais cela sera bien du .webp sur les navigateurs compatibles, vous allez comprendre après.
Aussi, si vous avez une version à jour de Nginx, pas besoin d’indiquer le type mime. C’est déjà inclus.
Merci à Mats Thorburn pour sa configuration simple : https://matteth.wordpress.com/2014/09/29/serving-webp-images-in-wordpress-with-nginx/
Première chose, on doit d’abord enregistrer une variable dans Nginx pour faire la redirection vers le format webp après.
Créez un nouveau fichier de config :
nano /etc/nginx/conf.d/webp.conf
Ajoutez-y ceci :
map $http_accept $webp_suffix {
default "";
"~*webp" ".webp";
}
Maintenant, ouvrez le vhost de votre site web :
nano /etc/nginx/sites-enabled/abyssproject.vhost
Ajoutez une location pour l’envoie à la volée des images webp (on ne fait pas une redirection ici, on perdrait trop de temps).
On en profite pour ajouter le cache du WebP dans le bloc en dessous. L’exemple ici est valide pour WordPress :
location ~* ^/wp-content/uploads/.+\.(png|jpg)$ {
add_header Vary Accept;
try_files $uri$webp_suffix $uri =404;
}
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|css|js|woff|woff2|webp)$ {
expires max;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
Rechargez la configuration de Nginx :
systemctl reload nginx
La partie marrante maintenant. Vous ne verrez pas que ce sont des images WebP à l’œil nu.
Comment qu’on fait ? Firefox vous le dira si vous allez sur l’url direct d’une image, par exemple :
Marrant non ? C’est l’url d’une image .png, mais c’est bien reconnu comme une image WebP.
Curieux non ? En fait c’est le Nginx qui modifie le suffixe de l’image sans que vous ne le voyiez.
C’est plus parlant avec les options développeurs en mode analyse réseau :